package com.hwd.srb.core.service.impl;

import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.core.conditions.update.LambdaUpdateWrapper;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.hwd.srb.core.enmu.BorrowInfoStatusEnum;
import com.hwd.srb.core.enmu.BorrowerStatusEnum;
import com.hwd.srb.core.mapper.BorrowInfoMapper;
import com.hwd.srb.core.mapper.BorrowerMapper;
import com.hwd.srb.core.mapper.IntegralGradeMapper;
import com.hwd.srb.core.mapper.UserInfoMapper;
import com.hwd.srb.core.pojo.entity.BorrowInfo;
import com.hwd.srb.core.pojo.entity.Borrower;
import com.hwd.srb.core.pojo.entity.IntegralGrade;
import com.hwd.srb.core.pojo.vo.BorrowInfoApprovalVO;
import com.hwd.srb.core.pojo.vo.BorrowerDetailVO;
import com.hwd.srb.core.service.BorrowInfoService;
import com.hwd.srb.core.service.BorrowerService;
import com.hwd.srb.core.service.LendService;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import javax.annotation.Resource;
import java.math.BigDecimal;
import java.math.RoundingMode;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.Objects;

/**
 * <p>
 * 借款信息表 服务实现类
 * </p>
 *
 * @author 黄伟东/Victor
 * @since 2022-03-10
 */
@Service
public class BorrowInfoServiceImpl extends ServiceImpl<BorrowInfoMapper, BorrowInfo> implements BorrowInfoService {

    @Resource
    private UserInfoMapper userInfoMapper;

    @Resource
    private IntegralGradeMapper integralGradeMapper;

    @Resource
    private BorrowerService borrowerService;

    @Resource
    private LendService lendService;

    /**
     * 从请求头里获取JWT令牌token，再解析token获取userId
     * 根据userId获取当前用户借款额度
     *
     * @param userId 用户id
     * @return java.math.BigDecimal
     */
    @Override
    public BigDecimal getBorrowAmount(Long userId) {

        // 查询user_info表，根据userId查询当前用户积分
        Integer integral = userInfoMapper.selectById(userId).getIntegral();

        // 查询integral_grade表，获取借款额度
        LambdaQueryWrapper<IntegralGrade> integralGradeQueryWrapper = new LambdaQueryWrapper<IntegralGrade>()
                .select(IntegralGrade::getBorrowAmount)
                .le(IntegralGrade::getIntegralStart, integral) // 数据库<integral
                .gt(IntegralGrade::getIntegralEnd, integral); // 数据库>integral
        IntegralGrade integralGrade = integralGradeMapper.selectOne(integralGradeQueryWrapper);

        return integralGrade != null ? integralGrade.getBorrowAmount() : new BigDecimal("0");
    }

    /**
     * 提交借款申请
     *
     * @param borrowInfo 提交借款申请
     */
    @Override
    public void saveBorrowInfo(BorrowInfo borrowInfo) {

        // 获取数据，准备数据
        borrowInfo.setBorrowYearRate(borrowInfo.getBorrowYearRate().divide(new BigDecimal("100"), 2, RoundingMode.HALF_UP));
        borrowInfo.setStatus(BorrowInfoStatusEnum.CHECK_RUN);//TODO 改用枚举类型

        // 在borrow_info中插入数据
        baseMapper.insert(borrowInfo);
    }

    /**
     * 根据用户id获取借款申请审批状态
     *
     * @param userId 用户id
     * @return java.lang.Integer
     */
    @Override
    public Integer getBorrowInfoStatus(Long userId) {

        Integer borrowInfoStatus = 0;

        LambdaQueryWrapper<BorrowInfo> queryWrapper = new LambdaQueryWrapper<BorrowInfo>()
                .select(BorrowInfo::getStatus)
                .eq(BorrowInfo::getUserId, userId);
        BorrowInfo borrowInfo = baseMapper.selectOne(queryWrapper);

        if (borrowInfo != null) {
            borrowInfoStatus = borrowInfo.getStatus().getStatus();//TODO 改用枚举类型
        }

        return borrowInfoStatus;
    }

    /**
     * 借款信息列表
     *
     * @return java.util.List<com.hwd.srb.core.pojo.entity.BorrowInfo>
     */
    @Override
    public List<BorrowInfo> selectList() {

        return baseMapper.selectBorrowInfoList();
    }

    /**
     * 根据借款信息id获取借款信息
     *
     * @param borrowInfoId 借款信息id
     * @return java.util.Map<java.lang.String, java.lang.Object>
     */
    @Override
    public Map<String, Object> show(Long borrowInfoId) {

        Map<String, Object> borrowInfoDetail = new HashMap<>();
        // 根据借款信息id获取borrow_info信息
        BorrowInfo borrowInfo = baseMapper.selectById(borrowInfoId);

        // 获取borrower信息 is_marry枚举 industry return_source status
        LambdaQueryWrapper<Borrower> queryWrapper = new LambdaQueryWrapper<Borrower>()
                .select(Borrower::getId)
                .eq(Borrower::getUserId, borrowInfo.getUserId());
        Borrower borrower = borrowerService.getOne(queryWrapper);

        BorrowerDetailVO borrowerDetailVO = new BorrowerDetailVO();

        if (Objects.nonNull(borrower)) {
            borrowerDetailVO = borrowerService.show(borrower.getId());
        }

        borrowInfoDetail.put("borrowInfo", borrowInfo);
        borrowInfoDetail.put("borrower", borrowerDetailVO);

        return borrowInfoDetail;
    }

    /**
     * 获取借款审核对象，进行审核
     * （插入数据，考虑幂等性），事务控制
     * 审核通过后：
     * 1）修改借款申请状态(borrow_info表)
     * 2）创建标的lend标的数据结构(lend表) 幂等性
     *
     * @param borrowInfoApprovalVO 借款审核对象
     */
    @Transactional
    @Override
    public void approval(BorrowInfoApprovalVO borrowInfoApprovalVO) {

        // 1）修改借款申请状态(borrow_info表)
        BorrowInfo borrowInfo = baseMapper.selectById(borrowInfoApprovalVO.getId());
        borrowInfo.setStatus(BorrowInfoStatusEnum.CHECK_OK);
        baseMapper.updateById(borrowInfo);

        // 2）创建标的lend标的数据结构(lend表)，调用lendService
        // 审核通过再创建标的
        if (Objects.equals(borrowInfoApprovalVO.getStatus(), BorrowInfoStatusEnum.CHECK_OK.getStatus())) {
            lendService.createLend(borrowInfoApprovalVO,borrowInfo);
        }

    }
}
